package cn.npe.dynamic.thread.pool.sdk.domain.model.entity;

import cn.npe.dynamic.thread.pool.sdk.domain.factory.DtpThreadFactory;
import org.springframework.beans.factory.InitializingBean;

import java.util.concurrent.*;

public class DtpThreadPoolExecutor extends ThreadPoolExecutor implements InitializingBean {
    private  ThreadPoolProperties  executorProp;
    public DtpThreadPoolExecutor(ThreadPoolProperties executorProp) {
        super(
                executorProp.getCorePoolSize(),
                executorProp.getMaximumPoolSize(),
                executorProp.getKeepAliveTime(),
                executorProp.getTimeUnit(),
                new ArrayBlockingQueue<>(executorProp.getQueueSize()),
                new DtpThreadFactory(executorProp.getThreadFactoryPrefix(),executorProp.getPoolName())
        );
        this.executorProp=executorProp;
    }


    public DtpThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,RejectedExecutionHandler rejectedExecutionHandler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,rejectedExecutionHandler);
    }

    private BlockingQueue getQueue(ThreadPoolProperties poolProperties){

        BlockingQueue blockingQueue;
        switch (poolProperties.getQueueType()){
            case "ArrayBlockingQueue":
                blockingQueue= new ArrayBlockingQueue<>(poolProperties.getQueueSize());
                break;
            case "LinkedBlockingDeque":
                blockingQueue = new LinkedBlockingDeque<>(poolProperties.getQueueSize());
                break;
            default:
                blockingQueue = new LinkedBlockingDeque<>(poolProperties.getQueueSize());
                break;
        }
        return  blockingQueue;
    }


    public RejectedExecutionHandler getHandler(ThreadPoolProperties poolProperties){
        // 实例化策略
        RejectedExecutionHandler handler;
        switch (poolProperties.getRejectedExecutionHandler()){
            case "AbortPolicy":
                handler = new ThreadPoolExecutor.AbortPolicy();
                break;
            case "DiscardPolicy":
                handler = new ThreadPoolExecutor.DiscardPolicy();
                break;
            case "DiscardOldestPolicy":
                handler = new ThreadPoolExecutor.DiscardOldestPolicy();
                break;
            case "CallerRunsPolicy":
                handler = new ThreadPoolExecutor.CallerRunsPolicy();
                break;
            default:
                handler = new ThreadPoolExecutor.AbortPolicy();
                break;
        }
        return handler;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.setRejectedExecutionHandler(getHandler(this.executorProp));
    }
}